package com.klikmee.sms.core.base.handlers;

import java.text.MessageFormat;

import org.apache.log4j.Logger;

import com.klikmee.sms.core.base.EventManager;
import com.klikmee.sms.core.base.EventParams;
import com.klikmee.sms.core.base.creators.MessageCreator;
import com.klikmee.sms.core.base.dao.IncomingMessageDAO;
import com.klikmee.sms.core.base.dao.ServiceDAO;
import com.klikmee.sms.core.base.util.States;
import com.klikmee.sms.core.commons.events.AppEvent;
import com.klikmee.sms.core.commons.events.EventListener;
import com.klikmee.sms.core.model.IncomingMessage;
import com.klikmee.sms.core.model.Service;
import com.klikmee.sms.core.model.ServiceChargingCategory;

public class IncomingMessageEventHandler implements EventListener {

	private Logger				logger					= Logger.getLogger( IncomingMessageEventHandler.class );
	/**
	 * Instance of services
	 */
	private Service				badRequestService		= null;
	private Service				freeOfChargeService;
	/**
	 * Ids used to load badRequest and freeOfCharge services
	 */
	private Long				badRequestServiceId		= null;
	private Long				freeOfChargeServiceId	= null;

	private String				serviceNotAvailableMessageText;
	/**
	 * Dao for incoming messages
	 */
	private IncomingMessageDAO	incomingMessageDAO;

	private ServiceDAO			serviceDAO				= null;

	/**
	 * Message creator used to create charged and bulk messages
	 */
	private MessageCreator		messageCreator			= null;

	/**
	 * 
	 */
	private String				badSintaxMessageText;

	public void init() {
		badRequestService = serviceDAO.find( this.badRequestServiceId );
		logger.debug( MessageFormat.format( "Loaded [{0}] service from database", badRequestService != null ? badRequestService.getName() : "Failed" ) );
		freeOfChargeService = serviceDAO.find( this.freeOfChargeServiceId );
		logger.debug( MessageFormat.format( "Loaded [{0}] service from database", freeOfChargeService != null ? freeOfChargeService.getName() : "Failed" ) );
	}

	@Override
	public void handleEvent(AppEvent appEvent) {
		String eventType = appEvent.getEventType();
		if (eventType.equals( EventManager.INCOMING_MESSAGE_UNRESOLVED )) {
			logger.debug( MessageFormat.format( "Processing [{0}] event", eventType ) );
			onIncomingMessageUnresolved( appEvent );
		}

		if (eventType.equals( EventManager.SERVICE_UNAVAILABLE )) {
			onServiceUnavailable( appEvent );
		}

	}

	private void onServiceUnavailable(AppEvent appEvent) {
		// extract incoming message from event
		IncomingMessage incomingMessage = appEvent.<IncomingMessage> getData();

		// send info message to user
		messageCreator.createResponse( incomingMessage, this.freeOfChargeService.getServiceChargingCategoryList().iterator().next(), this.serviceNotAvailableMessageText );
		// and set im state
		incomingMessage.setState( States.IncommingMessage.SERVICE_NOT_AVAILABLE_NOTIFICATION_SENT );
		incomingMessageDAO.edit( incomingMessage );

		logger.info( MessageFormat.format( "Could not deliver message to service named [{0}], message id = [{1}], user notification sent.", incomingMessage.getService().getName(),
				incomingMessage.getId() ) );
	}

	/**
	 * Sends bad request info message for request messages that could not be
	 * resolved to service. Updates incoming messages state to
	 * {@link States.IncommingMessage#BAD_SYNTAX_NOTIFICATION_SENT}
	 * 
	 * @param appEvent
	 */
	private void onIncomingMessageUnresolved(AppEvent appEvent) {
		// extract event data
		IncomingMessage incomingMessage = appEvent.<IncomingMessage> getData();

		// update incoming message
		incomingMessage.setService( badRequestService );
		incomingMessage.setState( States.IncommingMessage.BAD_SYNTAX_NOTIFICATION_SENT );
		incomingMessageDAO.create( incomingMessage );

		// send notification message
		ServiceChargingCategory serviceChargingCategory = this.badRequestService.getServiceChargingCategoryList().iterator().next();
		messageCreator.createResponse( incomingMessage, serviceChargingCategory, badSintaxMessageText );

		logger.info( MessageFormat.format( "Created bad syntax notification for [{0}], text[{1}]", incomingMessage, incomingMessage.getMessage() ) );
	}

	public void setIncomingMessageDAO(IncomingMessageDAO incomingMessageDAO) {
		this.incomingMessageDAO = incomingMessageDAO;
	}

	public void setMessageCreator(MessageCreator messageCreator) {
		this.messageCreator = messageCreator;
	}

	public void setBadSintaxMessageText(String badSintaxMessageText) {
		this.badSintaxMessageText = badSintaxMessageText;
	}

	public void setFreeOfChargeService(Service freeOfChargeService) {
		this.freeOfChargeService = freeOfChargeService;
	}

	public void setServiceNotAvailableMessageText(String serviceNotAvailableMessageText) {
		this.serviceNotAvailableMessageText = serviceNotAvailableMessageText;
	}

	public void setBadRequestService(Service badRequestService) {
		this.badRequestService = badRequestService;
	}

	public void setBadRequestServiceId(Long badRequestServiceId) {
		this.badRequestServiceId = badRequestServiceId;
	}

	public void setFreeOfChargeServiceId(Long freeOfChargeServiceId) {
		this.freeOfChargeServiceId = freeOfChargeServiceId;
	}

	public void setServiceDAO(ServiceDAO serviceDAO) {
		this.serviceDAO = serviceDAO;
	}
}
